#include "types.h"
#include "riscv.h"
#include "defs.h"
#include "trapframe.h"
#include "proc.h"
#include "printf.h"

void handle_exception(struct trapframe *tf) {
  // scause 最高位=0 表示同步异常
  uint64 cause = tf->scause & ((1ULL<<63)-1);
  struct proc *p = myproc();

  switch (cause) {
    case 8:   // Environment call from U-mode（按需调整）
    case 9:   // Environment call from S-mode
    case 11:  // Environment call from M-mode
      printf("syscall not implemented: scause=%lu sepc=%p stval=%p\n",
             cause, tf->sepc, tf->stval);
      tf->sepc += 4; // 跳过当前指令
      break;

    case 12:  // Instruction page fault
    printf("Instruction page fault: sepc=%p stval=%p pid=%d\n",
      tf->sepc, tf->stval, p ? p->pid : -1);
    if (p) {
    printf("Killing process %d due to instruction page fault\n", p->pid);
    p->killed = 1;
    return;
    }
    // 初始化阶段的指令页错误
    // sepc=0x2 看起来像是未初始化的函数指针
    // 可能是某个地方触发了异常，但PC指向了无效地址
    printf("ERROR: instruction page fault during initialization\n");
    printf("  sepc=%p (this looks like an uninitialized pointer)\n", tf->sepc);
    printf("  stval=%p\n", tf->stval);
    printf("  This might be caused by:\n");
    printf("  1. An uninitialized function pointer\n");
    printf("  2. A corrupted return address\n");
    printf("  3. An issue with page table mapping\n");
    panic("instruction page fault during initialization");

    case 13:  // Load page fault
      printf("Load page fault: sepc=%p stval=%p pid=%d\n",
             tf->sepc, tf->stval, p ? p->pid : -1);
      if (p) {
        printf("Killing process %d due to load page fault\n", p->pid);
        p->killed = 1;
        return;
      }
      // 初始化阶段的load页错误，直接panic
      panic("load page fault during initialization");

    case 15:  // Store/AMO page fault
      printf("Store page fault: sepc=%p stval=%p pid=%d\n",
             tf->sepc, tf->stval, p ? p->pid : -1);
      if (p) {
        printf("Killing process %d due to store page fault\n", p->pid);
        p->killed = 1;
        return;
      }
      // 初始化阶段的store页错误，直接panic
      panic("store page fault during initialization");

    default:
      printf("Unknown exception: scause=%p sepc=%p stval=%p pid=%d\n",
             tf->scause, tf->sepc, tf->stval, p ? p->pid : -1);
      if (p) {
        printf("Killing process %d due to unknown exception\n", p->pid);
        p->killed = 1;
        return;
      }
      panic("unknown exception during initialization");
  }
}